/**
 *******************************************************************************************************************************************
 * @file        dev_touch.c
 * @brief       TP 触摸设备驱动层
 * @details     /
 * @since       Change Logs:
 * Date         Author       Notes
 * 2022-12-08   lzh          the first version
 * @remark      /
 *******************************************************************************************************************************************
 * @attention
 *
 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
 * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
 * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
 * -ECTION WITH THEIR PRODUCTS.
 *
 * @copyright   2012 Synwit Technology
 *******************************************************************************************************************************************
 */
#include "dev_touch.h"


#if (TP_TYPE == TP_GT911)
#include "TP_GT911.h"
#elif (TP_TYPE == TP_FT6336)
#include "TP_FT6336.h"
#elif (TP_TYPE == TP_CST826)
#include "TP_CST826.h"
#elif (TP_TYPE == TP_FT5206)
#include "TP_FT5206.h"
#elif (TP_TYPE == TP_CST328)
#include "TP_CST328.h"
#elif (TP_TYPE == TP_TANGO_C32)
#include "TP_Tango_C32.h"
#elif (TP_TYPE == TP_ILI2117A)
#include "TP_ILI2117A.h"
#elif(TP_TYPE == TP_RTP01)
#include "TP_RTP01.h"
#else
#error "You must provide your customized resolution Driver!"
#endif

#define TP_MAX_POINTS        (1) /**< 电容屏支持的点数,固定最大为5点 */

/*******************************************************************************************************************************************
 * Private Prototype
 *******************************************************************************************************************************************/
/**
 * @brief   关闭 Touch 设备通讯接口, 进入低功耗前使用
 * @note    Touch IC 自身一般支持通过发送指令设置来进入低功耗/休眠模式, 详见各型号数据手册/驱动实现.
 */
static void touch_close(void);

/*******************************************************************************************************************************************
 * Private Variable
 *******************************************************************************************************************************************/
/** 中断标志 */
typedef enum
{
    NO = 0, /**< 未触发中断 */
    OK      /**< 已触发中断 */
    /* 可以枚举拓展 ++ 累计触发次数 */
} irq_flag_t;

/** TP_INT 边沿脉冲触发标志 */
static volatile uint8_t IRQ_Flag_TP = NO;

/** 触摸点数据流 */
static tp_data_t TP_Points_Data[TP_MAX_POINTS];

/*******************************************************************************************************************************************
 * Public Variable
 *******************************************************************************************************************************************/
dev_tp_t Dev_TP =
{
    .point = TP_Points_Data,
    .points_num = TP_MAX_POINTS,
    .type = TP_TYPE_RT,
    .mode = TP_MODE_INT_RX,

    /* Callback Register */
    #if (TP_TYPE == TP_GT911)
    .init_cb = gt9x_init,
    .read_cb = gt9x_read_points,
    .close_cb = touch_close,

    #elif (TP_TYPE == TP_FT6336)
    .init_cb = ft6336_init,
    .read_cb = ft6336_read_points,
    .close_cb = touch_close,

    #elif (TP_TYPE == TP_CST826)
    .init_cb = cst826_init,
    .read_cb = cst826_read_points,
    .close_cb = touch_close,

    #elif (TP_TYPE == TP_FT5206)
    .init_cb = ft5206_init,
    .read_cb = ft5206_read_points,
    .close_cb = touch_close,

    #elif (TP_TYPE == TP_CST328)
    .init_cb = cst328_init,
    .read_cb = cst328_read_points,
    .close_cb = touch_close,

    #elif (TP_TYPE == TP_TANGO_C32)
    .init_cb = tango_c32_init,
    .read_cb = tango_c32_read_points,
    .close_cb = touch_close,

    #elif (TP_TYPE == TP_ILI2117A)
    .init_cb = ili2117a_init,
    .read_cb = ili2117a_read_points,
    .close_cb = touch_close,

    #elif (TP_TYPE == TP_RTP01)
    .init_cb = rtpx_init,
    .read_cb = rtpx_read_points,
    .close_cb = touch_close,

    #else
#error "You must provide your customized resolution Driver!"
    #endif
};
/*******************************************************************************************************************************************
 * Public Function
 *******************************************************************************************************************************************/
/**
 * @brief   EXTI TP_INT ISR Callback (GPIO 输入边沿中断)
 */
void isr_exti_tp_int(void)
{
    if (EXTI_State(TP_GPIO_INT, TP_PIN_INT))
    {
        EXTI_Clear(TP_GPIO_INT, TP_PIN_INT);
        IRQ_Flag_TP = OK;
    }
}

/**
 * @brief   初始化触摸设备驱动
 * @param   dev : 设备句柄
 * @retval  0     : success
 * @retval  other : error code
 */
uint8_t touch_init(dev_tp_t *dev)
{
    uint8_t res = 1;
    for (uint16_t i = 0; i < dev->points_num; ++i)
    {
        dev->point[i].x = 0;
        dev->point[i].y = 0;
        dev->point[i].event = TP_EVENT_RELEASED;
        dev->point[i].width = 0;
        dev->point[i].track_id = 0;
    }
    res = dev->init_cb();
    if (dev->mode == TP_MODE_INT_RX)
    {
        /* 中断方式选用边沿触发，则需要在 TP_IC 初始化中设置 TP 芯片的扫描方式为中断触发，
         * 如此才能使得长时间按压时不断触发 TP_INT 边沿脉冲信号
         */
        GPIO_Init(TP_GPIO_INT, TP_PIN_INT, 0, 1, 0, 0);
        EXTI_Init(TP_GPIO_INT, TP_PIN_INT, EXTI_BOTH_EDGE); /* EXTI_FALL_EDGE - 下降沿触发 / EXTI_RISE_EDGE - 上升沿触发 */
        NVIC_EnableIRQ(TP_INT_IRQn);
        EXTI_Open(TP_GPIO_INT, TP_PIN_INT);
    }
    return res;
}

/**
 * @brief   触摸事件处理
 * @param   dev : 设备句柄
 * @retval  /
 * @note    INT 中断触发->查询扫描
 */

void touch_handler(dev_tp_t *dev)
{
    uint8_t points = 0;
    if (dev->mode == TP_MODE_INT_RX) /* 中断 INT 触发模式 */
    {
        if (IRQ_Flag_TP == OK)
        {
            IRQ_Flag_TP = NO;
            points = dev->read_cb(dev->point, 1);
         
//            printf("Your Touch point num = [%d], event <%s>, [x] = [%d], [y] = [%d]\r\n",
//                   points, (dev->point[0].event == TP_EVENT_PRESSED) ? "press" : "release", dev->point[0].x, dev->point[0].y
//            );
        }
    }
    else if (dev->mode == TP_MODE_POLLING_RDONLY) /* 轮询读取模式 */
    {
        points = dev->read_cb(dev->point, 1);
    }
    if (dev->point->event == TP_EVENT_PRESSED)
    {
        /* 手指触摸释放时长 */
        extern volatile uint32_t Systick_Ms_TP;
        Systick_Ms_TP = 0;
    }
}

/*******************************************************************************************************************************************
 * Private Function
 *******************************************************************************************************************************************/
/**
 * @brief   关闭 Touch 设备通讯接口, 进入低功耗前使用
 * @note    Touch IC 自身一般支持通过发送指令设置来进入低功耗/休眠模式, 详见各型号数据手册/驱动实现.
 */
static void touch_close(void)
{
    NVIC_DisableIRQ(TP_INT_IRQn);
    EXTI_Close(TP_GPIO_INT, TP_PIN_INT);
    I2C_Close(TP_I2C_X);
}
